<?php

namespace app\devices\controller;

use app\data\service\UserService;
use app\devices\service\BoxService;
use app\devices\service\DevicesService;
use app\devices\service\OrderService;
use app\devices\service\SocketService;
use think\admin\Controller;
use think\admin\extend\CodeExtend;
use think\cache\driver\Redis;

/**
 * 订单管理
 * Class Order
 * @package app\data\controller
 */
class Order extends Controller
{
    /**
     * 绑定数据表
     * @var string
     */
    private $table = 'JcgDevicesOrder';

    protected $box_types = [1=>'大柜', 2=>'中柜', 3=>'小柜'];
    protected $fee_types = [3=>'按时', 2=>'按次', 1=>'免费'];
    protected $arr_status = [0=>'待支付',1=>'进行中',2=>'已完成',4=>'超时订单'];

    /**
     * 订单管理
     * @auth true
     * @menu true
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function index(){
        $this->title = '订单管理';
        $this->assign("status", input("status", 1));

        $where = $s_map = [];
        $map = "";

        $where[] = ['deleted', "=", 0];
        $where[] = ['pid', "=", 0];

        $user = $this->app->session->get("user");
        $stores = str2arr($user['stores'] ?? '');
        if($user['id']!=10000){
            if($stores) {
                $s_map[] = ['id', "in", $stores];
                $where[] = ['store_id', "in", $stores];
            }
        }
        $this->user_stores = $stores;

        $this->stores = $this->app->db->name('JcgStore')->where($s_map)->column('name, end_hours, bus_hours', 'id');

        $this->devices = $this->app->db->name("jcg_devices")->where("store_id", 'in', array_keys($this->stores))->column("device_name, store_id", 'id');

        $s_id = input("s_id", '');
        if($s_id){
            $d_ids = $this->app->db->name("jcg_store")
                ->alias("s")
                ->leftJoin("jcg_devices d", 'd.store_id=s.id')
                ->where("s.id", $s_id)
                ->column("d.id");
            $where[] = ['d_id', "in", $d_ids];
        }

        $title = input("title", '');
        if($title){
            $u_ids = $this->app->db->name("data_user")
                ->where("nickname|phone", 'like','%'.$title.'%')
                ->column("id");
            $where[] = ['user_id', "in", $u_ids];
        }

        $d_id = input("d_id", '');
        if($d_id){
            $where[] = ['d_id', "=", $d_id];
        }

        $day = 3;

        $status = input("status", 1);
        if($status!==''){
            if($status==4){
                $map = "status=1 AND out_times=1";
            }else{
                $where[] = ['status', "=", $status];
            }

        }

        $query = $this->_query($this->table)->equal("id,order_no");

        if (input('output') === 'json') {
            $this->success('获取数据成功', $query->where($where)->where($map)->order("id DESC")->dateBetween('create_at')->page(true, false));
        }

        $query->where($where)->where($map)->order("id DESC")->dateBetween('create_at')->page();
    }

    public function delRedis(){
        $redis = new Redis();
        $cacheTime = $redis->get("clearOrderCache")??'2021-07-06 15:30:00';

        $time = date("Y-m-d H:i:s");

        $ids = $this->app->db->name($this->table)->where("create_at",">=",$cacheTime)->where("status",2)->column("id");
        foreach ($ids as $row){
            $redis->delete("order".$row);
        }
        $redis->set("clearOrderCache", $time);
    }

    public function logs(){
        $redis = new Redis();
        $id = input("id/d", '');
        $list = $redis->handler()->lrange("LockUnlock:".$id, 0, -1);

        $result = "";
        $strs = ['lock'=>'<font color="green">关门时间：</font>', 'unlock'=>'<font color="#ff5722">开门时间：</font>', 'temp-unlock'=>'<font color="#00008b">临时开门时间：</font>'];
        foreach ($list as $key=>$row){
            $info = explode("_", $row);
            if(($info[0]??0)){
                $info[0] = $strs[$info[0]]??'';
            }
            $result .= "<div style='margin: 10px;'>".$info[0].$info[1]."，此时的IP：".$info[2]."</div>";
        }
        if($result){
            echo("<div style='margin: 10px; font-size: 16px; line-height: 16px;'>".$result."</div>");
        }else{
            echo("<div style='margin: 10px; text-align: center; font-size: 16px; line-height: 16px;'>暂无</div>");
        }

    }

    /**
     * 数据列表处理
     * @param array $data
     */
    protected function _page_filter(array &$data)
    {
        $u_ids = array_column($data, 'user_id');
        $o_ids = array_column($data, 'id');

        $users = $this->app->db->name("data_user")->where("id", "in", $u_ids)->column("nickname, phone", "id");

        $codes = $this->app->db->name("jcg_device_pickupcode")->where("order_id", "in", $o_ids)->column("code", "order_id");

        if($data){

            $redis = new Redis();

            foreach ($data as &$row){
//                $end_hours = strtotime(date("Y-m-d",$row['create_time']).$this->stores[$row['store_id']]['end_hours']);
                $extends = json_decode($row['extends'], true);
                $row['device_name'] = $extends['device_name'];

                if($row['fee_type']!=3){
                    $row['amount_total'] = in_array($row['status'], [2,3])?$row['amount']:'计算中';
                }else if($row['status']==1){
                    $row['amount_total'] = in_array($row['status'], [2,3])?$row['amount']:'计算中';
                }

                $row['store_name'] = $this->stores[$this->devices[$row['d_id']]['store_id']??0]??'';
                if($row['status']==1 && $row['out_times']==1){
                    $row['status'] = 4;
                }
                $row['code'] = isset($codes[$row['id']])?'（'.$codes[$row['id']].'）':'';
                $row['create_time'] = $row['create_time']?date("Y-m-d H:i:s", $row['create_time']):"";
                $row['reality_end_time'] = $row['reality_end_time']?date("Y-m-d H:i:s", $row['reality_end_time']):"";
                $row['nickname'] = $users[$row['user_id']]['nickname']??$row['user_id'];
                $row['mobile'] = $users[$row['user_id']]['phone']??"";

                $row['mobile_str'] = $row['mobile'].$row['code'];
                $row['fee_type_str'] = $this->fee_types[$row['fee_type']]??'';
                $row['status_str'] = $this->arr_status[$row['status']]??'';

                $row['box_num'] = $extends['box_num']??0;

                $row['show_logs'] = $redis->handler()->llen("LockUnlock:".$row['id'])??0;
            }
        }
    }

    /**
     * 修改订单状态
     * @auth true
     * @throws \think\db\exception\DbException
     */
    public function state()
    {
        $this->_save($this->table, $this->_vali([
            'status.in:0,1'  => '状态值范围异常！',
            'status.require' => '状态值不能为空！',
        ]));
    }

    /**
     * 删除订单
     * @auth true
     * @throws \think\db\exception\DbException
     */
    public function remove()
    {
        $this->_delete($this->table);
    }

    public function end_order(){
        $id = input("id/d", '');
        if($id){
            $order = OrderService::instance()->get('',['id'=>$id, 'status'=>1]);
            if(empty($order)){
                $this->success("当前没有可以打开的柜子");
            }

            $data['reality_end_time'] = time();

            $extends = json_decode($order['extends'], true);
            $extends['ip'] = $this->app->request->ip();

            $out_money = 0;
            if($order['fee_type']==3){
                $re_amount = ceil((time()-$order['create_time']-$order['free_hours']*3600)/3600)*$order['amount'];
                $re_amount = $re_amount>0?$re_amount:0;
                if(in_array($order['store_id'], OrderService::instance()->special_store) && $re_amount){
                    $re_amount = $re_amount<2?2:$re_amount;
                }

                $out_money = OrderService::instance()->getRefund($order);
                $max_money = $extends['max_money']??0;
                if($re_amount>$max_money){
                    $re_amount = $max_money;
                }
                if($order['money']<$re_amount && !$out_money){

                }else{
                    $order['refund'] = $order['money']-$re_amount;
                }
            }

            $this->app->db->startTrans();

            unset($data['order_id']);
            $data['reality_end_time'] = time();
            $data['status'] = 2;
            $data['s_id'] = $this->app->session->get("user.id");

            if($order['fee_type']==3){
                if($order['refund']>0){
                    $extends['refund'] = $order['refund'];
                    $refund = OrderService::instance()->refund($order);
                    if(is_array($refund)){
                        $data['out_refund_no'] = $refund['out_refund_no'];
                        if(empty($refund['out_refund_no'])){
                            $extends['refund_error'] = $refund['err_code_des'];
                        }
                    }
                    $data['amount_total'] = $order['money']-$order['refund']+$out_money;
                }else{
                    $data['amount_total'] = $order['money']+$out_money;
                }
            }else{
                $data['amount_total'] = $order['money'];
            }

            $data['extends'] = json_encode($extends, 256);

            $res = 1;
            try {
                $res_a = OrderService::instance()->endOrder($order['id'], $data);
                $res_b = BoxService::instance()->updateBox($order['box_id'], ['user_id'=>0, 'box_status'=>1]);
                $res_c = DevicesService::instance()->usePickUpCode(['order_id'=>$order['id'], 'user_id'=>$order['user_id']]);

                if($res_a && $res_b && $res_c){
                    $this->app->db->commit();
                }else{
                    $this->app->db->rollback();
                    $res = 0;
                }
            }catch (\Exception $e){
                $this->app->db->rollback();
                $this->error("失败:".$e->getMessage());
            }
            if($res){
                $device = DevicesService::instance()->getDevice($order['d_id']);
                $msg = ['type'=>2, 'device_id'=>$device['device_id'], 'ch'=>$order['board_channel'], 'device_board'=>$order['device_board']];
                SocketService::instance()->sendSocket($msg);

                //删除超时定时任务对应订单缓存
                OrderService::instance()->clearOutTimeOrderCache($order);

                //移除已使用的箱子ID
                $redis = new Redis();
                $redis->handler()->ZREM("orderUseBox".$order['d_id'], $order['box_id']);

                $msg_str = "成功";
                $openid = UserService::instance()->getOpenid($order['user_id']);
                if($openid){
                    try {
                        OrderService::instance()->sendTemp(2, $openid, [$extends['device_name'], ($extends['box_num']<10?'0'.$extends['box_num']:$extends['box_num']).'号', sprintf("%.2f", $data['amount_total']).'元', date("Y-m-d H:i", $order['create_time']), date("Y-m-d H:i")],'','感谢你的使用！如有物品未取，请联系：'.($extends['store_contact']??''));
                    }catch (\Exception $e){
                        $msg_str.="，但是发送推送失败了：".$e->getMessage();
                    }
                }

                $this->success($msg_str);
            }else{
                $this->app->db->rollback();
                $this->error("失败1");
            }
        }else{
            $this->error("订单ID不能为空");
        }
    }

}